package epidemic

import (
	"errors"
	"gitee.com/baal1990/epidemic/global"
	"gitee.com/baal1990/epidemic/model/common/request"
	response "gitee.com/baal1990/epidemic/model/common/response_dfitc"
	"gitee.com/baal1990/epidemic/model/epidemic"
	epidemicReq "gitee.com/baal1990/epidemic/model/epidemic/request"
	"gitee.com/baal1990/epidemic/service"
	"gitee.com/baal1990/epidemic/utils"
	"gitee.com/baal1990/epidemic/utils/validator"
	"github.com/gin-gonic/gin"
	"github.com/go-sql-driver/mysql"
	"go.uber.org/zap"
	"io"
	"path"
	"regexp"
)

type EpidemicUserApi struct {
}

var epidemicUserService = service.ServiceGroupApp.EpidemicServiceGroup.EpidemicUserService

// CreateOrUpdateEpidemicUser 创建EpidemicUser
// @Tags EpidemicUser
// @Summary 创建EpidemicUser
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body epidemic.EpidemicUser true "创建EpidemicUser"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /epidemicUser/createEpidemicUser [post]
func (epidemicUserApi *EpidemicUserApi) CreateOrUpdateEpidemicUser(c *gin.Context) {
	operaterUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var queryUser epidemic.EpidemicUser
	if err := c.ShouldBind(&queryUser); err != nil {
		global.GVA_LOG.Error("参数错误", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	// 处理加密字段
	if err := verifyCreateOrUpdateUserParams(&queryUser); err != nil {
		global.GVA_LOG.Error("解密失败", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", queryUser))
	//非超级管理员编辑时候判断
	if operaterUser.Role != global.DICT_ROLES_SUPER {
		if operaterUser.Company != queryUser.Company ||
			!validator.ValidateDepartment(operaterUser.Department, queryUser.Department) ||
			queryUser.Role == global.DICT_ROLES_SUPER {
			response.FailWithMessage("账号权限不足", c)
			return
		}
	}
	// 用户信息只要变动就是未审批
	queryUser.Status = global.DICT_USER_APPROVED_STATUS
	if queryUser.ID == 0 {
		if err := epidemicUserService.CreateEpidemicUser(queryUser); err != nil {
			global.GVA_LOG.Error("创建失败!", zap.Error(err))
			var mysqlErr *mysql.MySQLError
			if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
				//根据mysql错误号判断是否为重复键错误，如果是，则为mobile存在。
				response.FailWithMessage("更新失败：手机号已存在", c)
				return
			}
			response.FailWithMessage("创建失败", c)

		} else {
			response.OkWithMessage("创建成功", c)
		}
	} else {
		if err := epidemicUserService.UpdateEpidemicUser(queryUser); err != nil {
			global.GVA_LOG.Error("更新失败!", zap.Error(err))
			var mysqlErr *mysql.MySQLError
			if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
				//根据mysql错误号判断是否为重复键错误，如果是，则为mobile存在。
				response.FailWithMessage("更新失败：手机号已存在", c)
				return
			}
			response.FailWithMessage("更新失败", c)
		} else {
			response.OkWithMessage("更新成功", c)
		}
	}
}

func (epidemicUserApi *EpidemicUserApi) CreateOrUpdateEpidemicUserMobile(c *gin.Context) {
	var queryUser epidemic.EpidemicUser
	if err := c.ShouldBind(&queryUser); err != nil {
		global.GVA_LOG.Error("参数错误", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	if err := verifyCreateOrUpdateUserParams(&queryUser); err != nil {
		global.GVA_LOG.Error("解密失败", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", queryUser))
	// 手机端只要能查询用户，用户表中一定存在预设用户
	user := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	queryUser.ID = user.ID
	// 用户信息只要变动就是未审批
	queryUser.Status = global.DICT_USER_NOT_APPROVED_STATUS
	if err := epidemicUserService.UpdateEpidemicUserMobile(queryUser); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Error(err))
		var mysqlErr *mysql.MySQLError
		if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
			//根据mysql错误号判断是否为重复键错误，如果是，则为mobile存在。
			response.FailWithMessage("更新失败：手机号已存在", c)
			return
		}
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

// DeleteEpidemicUser 删除EpidemicUser
// @Tags EpidemicUser
// @Summary 删除EpidemicUser
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body epidemic.EpidemicUser true "删除EpidemicUser"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /epidemicUser/deleteEpidemicUser [delete]
func (epidemicUserApi *EpidemicUserApi) DeleteEpidemicUser(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		global.GVA_LOG.Error("参数错误!id 为 0!!!")
		response.FailWithMessage("参数错误", c)
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", id))
	if err := epidemicUserService.DeleteEpidemicUser(id); err != nil {
		global.GVA_LOG.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
	} else {
		response.OkWithMessage("删除成功", c)
	}
}

// DeleteEpidemicUserByIds 批量删除EpidemicUser
// @Tags EpidemicUser
// @Summary 批量删除EpidemicUser
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除EpidemicUser"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /epidemicUser/deleteEpidemicUserByIds [delete]
func (epidemicUserApi *EpidemicUserApi) DeleteEpidemicUserByIds(c *gin.Context) {
	var IDS request.IdsReq
	_ = c.ShouldBindJSON(&IDS)
	if err := epidemicUserService.DeleteEpidemicUserByIds(IDS); err != nil {
		global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
		response.FailWithMessage("批量删除失败", c)
	} else {
		response.OkWithMessage("批量删除成功", c)
	}
}

// FindEpidemicUser 用id查询EpidemicUser
// @Tags EpidemicUser
// @Summary 用id查询EpidemicUser
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query epidemic.EpidemicUser true "用id查询EpidemicUser"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /epidemicUser/findEpidemicUser [get]
func (epidemicUserApi *EpidemicUserApi) FindEpidemicUser(c *gin.Context) {
	var epidemicUser = c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	if reepidemicUser, err := epidemicUserService.GetEpidemicUser(epidemicUser.ID); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		response.OkWithData(gin.H{"reepidemicUser": reepidemicUser}, c)
	}
}

// GetEpidemicUserList 分页获取EpidemicUser列表
// @Tags EpidemicUser
// @Summary 分页获取EpidemicUser列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query epidemicReq.EpidemicUserSearch true "分页获取EpidemicUser列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /epidemicUser/getEpidemicUserList [get]
func (epidemicUserApi *EpidemicUserApi) GetEpidemicUserList(c *gin.Context) {
	epidemicUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var pageInfo epidemicReq.EpidemicUserSearch
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		global.GVA_LOG.Error("参数错误", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	// name 参数需要rsa解密
	if pageInfo.Name != "" {
		nameDecodeBytes, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(pageInfo.Name)
		if err != nil {
			global.GVA_LOG.Error("解密失败", zap.Error(err))
			response.FailWithMessage("参数错误", c)
			return
		}
		pageInfo.Name = string(nameDecodeBytes)
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", pageInfo))
	if list, total, err := epidemicUserService.GetEpidemicUserInfoList(pageInfo, epidemicUser); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithDetailed(response.PageResult{
			List:     list,
			Total:    total,
			Page:     pageInfo.Page,
			PageSize: pageInfo.PageSize,
		}, "获取成功", c)
	}
}

/*
*
催办功能
*/
func (epidemicUserApi *EpidemicUserApi) Urge(c *gin.Context) {
	operator := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var req epidemicReq.EpidemicUserUrge
	err := c.ShouldBind(&req)
	if err != nil {
		global.GVA_LOG.Error("参数错误：" + err.Error())
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", req))
	if err = epidemicUserService.Urge(req, operator); err != nil {
		global.GVA_LOG.Error("催办失败!", zap.Error(err))
		response.FailWithMessage("催办失败", c)
	} else {
		response.OkWithMessage("催办成功", c)
	}
}

/*
*
审核用户
*/
func (epidemicUserApi *EpidemicUserApi) VerifyEpidemicUser(c *gin.Context) {
	var epidemicUserVerify epidemicReq.EpidemicUserVerify
	err := c.ShouldBind(&epidemicUserVerify)
	if err != nil {
		response.FailWithMessage("参数错误："+err.Error(), c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", epidemicUserVerify))
	operationUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	epidemicUserVerify.ApprovedBy = operationUser.Name
	if err = epidemicUserService.VerifyEpidemicUser(epidemicUserVerify); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Error(err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

/*
*
数据字典功能
*/
func (epidemicUserApi *EpidemicUserApi) Dict(c *gin.Context) {
	var search epidemicReq.DictSearch
	err := c.ShouldBindQuery(&search)
	if err != nil {
		response.FailWithMessage("参数错误："+err.Error(), c)
		return
	}
	if list, err := epidemicUserService.GetDict(search); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithData(gin.H{"list": list}, c)

	}
}
func (epidemicUserApi *EpidemicUserApi) UploadFile(c *gin.Context) {
	formFile, header, err := c.Request.FormFile("file")
	if err != nil {
		global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
		response.FailWithMessage("接收文件失败", c)
		return
	}
	userId := "dfitc"
	fileName := header.Filename
	ext := path.Ext(fileName)
	extMatch, _ := regexp.MatchString("^(\\.doc|\\.docx|\\.xls|\\.xlsx)$", ext)
	if !extMatch {
		global.GVA_LOG.Error("上传文件失败, 文件名不匹配: ", zap.String("ext", ext))
		response.FailWithMessage("文件类型错误", c)
		return
	}

	uploadDir := global.GVA_CONFIG.System.DfitcUploadDir
	randomStr := string(utils.RandomCreateBytes(20))
	finalName := path.Join(uploadDir, userId, randomStr+ext)
	httpFilePath := path.Join(userId, randomStr+ext)
	out, err := utils.CreateFile(finalName)
	if err != nil {
		global.GVA_LOG.Error("上传文件失败", zap.Error(err))
		response.FailWithMessage("上传文件失败", c)
		return
	}
	defer out.Close()
	_, err = io.Copy(out, formFile)
	if err != nil {
		global.GVA_LOG.Error("上传文件失败", zap.Error(err))
		response.FailWithMessage("上传文件失败", c)
		return
	}
	response.OkWithData(gin.H{"path": httpFilePath}, c)

}

// ExportAll 导出全部用户列表excel
// @Tags ExportAll
// @Summary 导出全部用户列表excel
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /epidemic/user_list/export [get]
func (epidemicUserApi *EpidemicUserApi) ExportAll(c *gin.Context) {
	epidemicUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	fileName, err := epidemicUserService.ExportAllUsers(epidemicUser)
	if err != nil {
		global.GVA_LOG.Error("导出失败!", zap.Error(err))
		response.FailWithMessage("导出失败", c)
	} else {
		fileLinck := global.GVA_CONFIG.System.AccessHost + fileName
		response.OkWithData(fileLinck, c)
	}
}

// 对创建或更新用户的name、mobile、residentialAddressCode、 residentialAddressDetail进行rsa解码
func verifyCreateOrUpdateUserParams(user *epidemic.EpidemicUser) error {
	usernameByte, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(user.Name)
	if err != nil {
		return err
	}
	user.Name = string(usernameByte)

	mobileByte, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(user.Mobile)
	if err != nil {
		return err
	}
	user.Mobile = string(mobileByte)

	residentialAddressCodeByte, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(user.ResidentialAddressCode)
	if err != nil {
		return err
	}
	user.ResidentialAddressCode = string(residentialAddressCodeByte)

	residentialAddressNameByte, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(user.ResidentialAddressName)
	if err != nil {
		return err
	}
	user.ResidentialAddressName = string(residentialAddressNameByte)

	residentialAddressDetailByte, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(user.ResidentialAddressDetail)
	if err != nil {
		return err
	}
	user.ResidentialAddressDetail = string(residentialAddressDetailByte)
	return nil
}
